package me.zhengjie;

import cn.hutool.core.io.BufferUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.socket.nio.NioClient;
import cn.hutool.socket.nio.NioServer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.dreamlu.mica.core.utils.HexUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.*;

@SpringBootTest
public class MyTestSocket {

    @Autowired
    private WebApplicationContext applicationContext;

    @Test
    void testServer(){
        NioServer server = new NioServer(1111);
        server.setChannelHandler((sc)->{
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            try{
                //从channel读数据到缓冲区
                int readBytes = sc.read(readBuffer);
                if (readBytes > 0) {
                    //Flips this buffer.  The limit is set to the current position and then
                    // the position is set to zero，就是表示要从起始位置开始读取数据
                    readBuffer.flip();
                    //eturns the number of elements between the current position and the  limit.
                    // 要读取的字节长度
                    byte[] bytes = new byte[readBuffer.remaining()];
                    //将缓冲区的数据读到bytes数组
                    readBuffer.get(bytes);
                    String body = StrUtil.utf8Str(bytes);
                    Console.log("[{}]: {}", sc.getRemoteAddress(), body);
                    doWrite(sc, body);
                } else if (readBytes < 0) {
                    IoUtil.close(sc);
                }
            } catch (IOException e){
                throw new IORuntimeException(e);
            }
        });
        server.listen();
    }

    public static void doWrite(SocketChannel channel, String response) throws IOException {
        response = "收到消息：" + response;
        //将缓冲数据写入渠道，返回给客户端
        channel.write(BufferUtil.createUtf8(response));
    }

    @Test
    void testClient() {
        NioClient client = new NioClient("fdlpfjk.vecc.org.cn", 54001);
        client.setChannelHandler((sc)->{
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            //从channel读数据到缓冲区
            int readBytes = sc.read(readBuffer);
            if (readBytes > 0) {
                //Flips this buffer.  The limit is set to the current position and then
                // the position is set to zero，就是表示要从起始位置开始读取数据
                readBuffer.flip();
                //returns the number of elements between the current position and the  limit.
                // 要读取的字节长度
                byte[] bytes = new byte[readBuffer.remaining()];
                //将缓冲区的数据读到bytes数组
                readBuffer.get(bytes);
                String body = BinaryToHexString(bytes);
                Console.log("[{}]: {}", sc.getRemoteAddress(), body);
            } else if (readBytes < 0) {
                sc.close();
            }
        });
        client.listen();
        String hexStr = "23 23 07 FE 30 38 50 32 31 30 31 37 58 4E 34 30 30 30 30 30 31 01 00 29 16 0B 15 03 18 20 00 03 61 6C 63 7A 65 64 37 77 30 78 63 64 4A 66 31 32 33 34 35 36 37 2E 4A 66 31 32 33 34 35 36 37 2E 01 B4";
        client.write(BufferUtil.create(hexStringToByteArray(hexStr)));


//        client.write(BufferUtil.createUtf8("你好。\n"));
//        client.write(BufferUtil.createUtf8("你好2。"));
// 在控制台向服务器端发送数据
        Console.log("请输入发送的消息：");
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            String request = scanner.nextLine();
            if (request != null && request.trim().length() > 0) {
                client.write(BufferUtil.createUtf8(request));
            }
        }



    }

    /**
     * 将字节数组转换成十六进制的字符串
     *
     * @return
     */
    public static String BinaryToHexString(byte[] bytes) {
        String hexStr = "0123456789ABCDEF";
        String result = "";
        String hex = "";
        for (byte b : bytes) {
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            result += hex + " ";
        }
        return result;
    }

    /**
     * 16进制表示的字符串转换为字节数组
     *
     * @param hexString 16进制表示的字符串
     * @return byte[] 字节数组
     */
    public static byte[] hexStringToByteArray(String hexString) {
        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        byte[] bytes = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个字节
            bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character
                    .digit(hexString.charAt(i + 1), 16));
        }
        return bytes;
    }

    @Test
    void testClientA(){
        try {

//            Socket s = new Socket("fdlpfjk.vecc.org.cn",54001);
            Socket s = new Socket("127.0.0.1",9999);

            //构建IO
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();

            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            //向服务器端发送一条消息
            bw.write("##");
            bw.flush();

            //读取服务器返回的消息
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String mess = br.readLine();
            System.out.println("服务器："+mess);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    void testA() {
        String str = "##";
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        Integer i = 1;

        byte byte1 = i.byteValue();

        String xx = "11";
    }
    @Test
    void testB() {

        byte[] bytes = "##".getBytes(StandardCharsets.UTF_8);


    }
}
